﻿using AutojsController.Config;
using AutojsController.Helpers;
using AutojsController.Services;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
using Avalonia.Threading;
using ReactiveUI;
using Serilog;
using SukiUI.Dialogs;
using SukiUI.Toasts;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;

namespace AutojsController.ViewModels
{
    public class AddMobileDialogViewModel:ReactiveObject
    {
        private ISukiDialog dialog;
        private ISukiToastManager toastManager;
        private MobilesService mobService;
        public string? mobileIP;
        public string? MobileIP
        {
            get => mobileIP;
            set => this.RaiseAndSetIfChanged(ref mobileIP, value);
        }

        private bool _adding = false;
        public bool Adding
        {
            get => _adding;
            set
            {
                this.RaiseAndSetIfChanged(ref _adding, value);
                this.RaisePropertyChanged(nameof(AddButtonText));
            }
        }

        public string AddButtonText
        {
            get => _adding ? "添加中" : "添加";
        }

        private string? _addIP;

        public string? AddIP
        {
            get => _addIP;
            set => this.RaiseAndSetIfChanged(ref _addIP, value);
        }

        public ICommand CloseDialogCommand => ReactiveCommand.Create(closeDialog);
        public ICommand AddMobileCommand => ReactiveCommand.CreateFromTask(addMobile);
        private readonly ILogger logger = LoggerFactory.GetLogger();

        public AddMobileDialogViewModel(ISukiDialog dialog, ISukiToastManager toast, MobilesService mob)
        {
            this.dialog = dialog;
            this.toastManager = toast;
            this.mobService = mob;
        }

        private void closeDialog()
        {
            this.Adding = false;
            dialog.Dismiss();
        }

        private async Task addMobile()
        {
            if (string.IsNullOrWhiteSpace(AddIP)) return;
            this.Adding = true;
            logger.Information($"添加指定IP{AddIP}设备");
            var mc = await MobileConnectionService.CreateAndConnect(AddIP);
            if (mc == null)
            {
                Dispatcher.UIThread.Invoke(() =>
                {
                    SukiToast.Error(toastManager, $"{AddIP}连接失败");
                });
                this.Adding = false;
                dialog.Dismiss();
                return;
            }
            // hello成功回调并移除本次监听
            MessageReceivedEventHandler _handle = null!;
            bool _added = false;
            _handle = async (o, e) =>
            {
                logger.Information($"设备{AddIP}响应:{e.data}");
                if (e.data.ContainsKey("type") && e.data["type"]!.ToString() == "hello")
                {
                    await mobService.AddMobileAsync(AddIP, null, null);
                    var addedMobile = mobService.MobileItems.FirstOrDefault(m => m.Mobile.Address == AddIP.ToString());
                    if (addedMobile != null) addedMobile.connection = mc;
                    logger.Information($"添加设备{AddIP}");
                    _added = true;
                    mc.MessageReceived -= _handle;
                }
            };
            mc.MessageReceived += _handle;
            await mc.sendHello();
            // 如果socket超时时间内还没有添加成功就算失败
            var timer = new System.Timers.Timer(500);
            int _timePassed = 0;
            timer.Elapsed += (_, _) =>
            {
                Dispatcher.UIThread.Invoke(() =>
                {
                    if (_added)
                    {
                        SukiToast.Info(toastManager, "添加成功");
                    }
                    else
                    {
                        _timePassed += (int)timer.Interval;
                        if (_timePassed > Consts.SOCK_CONNECT_TIMEOUT)
                        {
                            logger.Error($"添加设备{AddIP}失败，远程无响应");
                            mc.Disconnect();
                            timer.Dispose();
                            SukiToast.Error(toastManager, $"{Consts.SOCK_CONNECT_TIMEOUT/1000}秒内手机端没有响应，添加{AddIP}失败", 3);
                        }
                        else return;
                    }
                    this.Adding = false;
                    dialog.Dismiss();
                });
            };
            timer.Start();
        }

        public void ShowToast(string message, NotificationType notificationType = NotificationType.Information,
                                int waitSeconds = 1)
        {
            toastManager.CreateToast().WithContent(message)
                .OfType(notificationType).Dismiss().After(TimeSpan.FromSeconds(waitSeconds))
                .Dismiss().ByClicking().Queue();
        }
    }
}
